#!/usr/bin/env node

/**
 * CreateTokenForm API 测试脚本
 * 测试后端代币创建接口的各种场景
 * 
 * 使用方法:
 * npm run test:api
 * 或
 * node scripts/test-api.js
 */

const axios = require('axios');

// 配置
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:7172';
const TIMEOUT = 30000;

// 测试数据
const testCases = [
  {
    name: '基础代币创建',
    description: '测试最基本的代币创建功能',
    data: {
      name: 'Test Basic Token',
      symbol: 'TBT',
      decimals: 9,
      supply: '1000000',
      description: '这是一个基础测试代币',
      creator: '11111111111111111111111111111112',
      enablePrettyAddress: false,
      revokeUpdateAuthority: false,
      revokeFreezeAuthority: false,
      revokeMintAuthority: false,
    },
  },
  
  {
    name: '靓号地址代币',
    description: '测试带靓号地址功能的代币创建',
    data: {
      name: 'Pretty Address Token',
      symbol: 'PAT',
      decimals: 6,
      supply: '500000',
      description: '带有靓号地址的测试代币',
      creator: '11111111111111111111111111111112',
      enablePrettyAddress: true,
      prettyPrefix: 'ABC',
      prettySuffix: '888',
      caseSensitive: false,
      threads: 2,
      revokeUpdateAuthority: false,
      revokeFreezeAuthority: false,
      revokeMintAuthority: false,
    },
  },
  
  {
    name: '完整功能代币',
    description: '测试包含所有功能的代币创建',
    data: {
      name: 'Full Feature Test Token',
      symbol: 'FFTT',
      decimals: 8,
      supply: '2000000',
      description: '包含所有功能的完整测试代币，用于验证各项配置是否正常工作',
      image: 'https://example.com/token-logo.png',
      creator: '11111111111111111111111111111112',
      enablePrettyAddress: true,
      prettyPrefix: 'FULL',
      prettySuffix: '999',
      caseSensitive: true,
      threads: 4,
      website: 'https://example.com',
      twitter: 'https://twitter.com/example',
      telegram: 'https://t.me/example',
      discord: 'https://discord.gg/example',
      revokeUpdateAuthority: true,
      revokeFreezeAuthority: true,
      revokeMintAuthority: false,
    },
  },
  
  {
    name: '边界值测试',
    description: '测试各字段的边界值',
    data: {
      name: 'A'.repeat(32), // 最大长度
      symbol: 'BOUNDARY', // 接近最大长度
      decimals: 0, // 最小值
      supply: '999999999999999999', // 大数值
      description: 'B'.repeat(500), // 最大描述长度
      creator: '11111111111111111111111111111112',
      enablePrettyAddress: true,
      prettyPrefix: 'ABCDEFGH', // 最大前缀长度
      prettySuffix: '12345678', // 最大后缀长度
      caseSensitive: true,
      threads: 16, // 最大线程数
      revokeUpdateAuthority: false,
      revokeFreezeAuthority: false,
      revokeMintAuthority: false,
    },
  },
];

// 错误测试用例
const errorTestCases = [
  {
    name: '缺少必填字段',
    description: '测试缺少必填字段时的错误处理',
    data: {
      symbol: 'ERR1',
      creator: '11111111111111111111111111111112',
      // 故意缺少 name 字段
    },
    expectError: true,
  },
  
  {
    name: '无效数据格式',
    description: '测试无效数据的错误处理',
    data: {
      name: '', // 空名称
      symbol: '', // 空符号
      decimals: -1, // 无效小数位
      supply: '-100', // 负数供应量
      creator: 'invalid-creator-address', // 无效地址
    },
    expectError: true,
  },
];

// 颜色输出
const colors = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  cyan: '\x1b[36m',
  magenta: '\x1b[35m',
};

function log(color, message) {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

// HTTP 客户端
const client = axios.create({
  baseURL: API_BASE_URL,
  timeout: TIMEOUT,
  headers: {
    'Content-Type': 'application/json',
  },
});

// 测试统计
let stats = {
  total: 0,
  passed: 0,
  failed: 0,
  errors: [],
};

// 健康检查
async function healthCheck() {
  try {
    log('blue', '🔍 检查后端服务健康状态...');
    const response = await client.get('/api/health');
    
    if (response.status === 200) {
      log('green', `✅ 后端服务运行正常 (${API_BASE_URL})`);
      if (response.data) {
        console.log('   服务信息:', response.data);
      }
      return true;
    } else {
      log('red', `❌ 后端服务状态异常: HTTP ${response.status}`);
      return false;
    }
  } catch (error) {
    log('red', `❌ 无法连接到后端服务: ${error.message}`);
    log('yellow', `   请确保后端服务在 ${API_BASE_URL} 上运行`);
    return false;
  }
}

// 测试靓号地址估算接口
async function testPrettyAddressEstimate() {
  try {
    log('cyan', '\n🧪 测试靓号地址难度估算接口...');
    
    const params = new URLSearchParams({
      prefix: 'TEST',
      suffix: '888',
      caseSensitive: 'false',
      threads: '2',
    });
    
    const response = await client.get(`/api/pretty-address/estimate?${params}`);
    
    if (response.data && response.data.success) {
      log('green', '✅ 靓号地址估算接口正常');
      console.log('   估算结果:', response.data.data);
    } else {
      log('yellow', '⚠️ 靓号地址估算接口返回异常');
    }
  } catch (error) {
    log('yellow', '⚠️ 靓号地址估算接口不可用 (这是可选功能)');
  }
}

// 执行单个测试用例
async function runTestCase(testCase) {
  stats.total++;
  const startTime = Date.now();
  
  try {
    log('cyan', `\n🧪 ${testCase.name}`);
    log('blue', `   ${testCase.description}`);
    console.log('   测试数据:', JSON.stringify(testCase.data, null, 4));
    
    const response = await client.post('/api/tokens', testCase.data);
    const duration = Date.now() - startTime;
    
    // 处理期望错误的测试用例
    if (testCase.expectError) {
      stats.failed++;
      stats.errors.push(`${testCase.name}: 期望返回错误但接口成功响应`);
      log('red', `❌ 测试失败: 期望错误但接口成功 (${duration}ms)`);
      return false;
    }
    
    // 检查响应状态
    if (response.status >= 200 && response.status < 300) {
      if (response.data && response.data.success) {
        stats.passed++;
        log('green', `✅ 测试通过 (${duration}ms)`);
        console.log('   返回结果:', JSON.stringify(response.data, null, 4));
        return true;
      } else {
        stats.failed++;
        const errorMsg = response.data?.message || '未知错误';
        stats.errors.push(`${testCase.name}: ${errorMsg}`);
        log('red', `❌ 接口返回失败: ${errorMsg} (${duration}ms)`);
        return false;
      }
    } else {
      stats.failed++;
      stats.errors.push(`${testCase.name}: HTTP ${response.status}`);
      log('red', `❌ HTTP状态码错误: ${response.status} (${duration}ms)`);
      return false;
    }
    
  } catch (error) {
    const duration = Date.now() - startTime;
    
    // 处理期望错误的测试用例
    if (testCase.expectError) {
      stats.passed++;
      log('green', `✅ 测试通过 (预期错误): ${error.response?.data?.message || error.message} (${duration}ms)`);
      return true;
    }
    
    stats.failed++;
    const errorMsg = error.response?.data?.message || error.message;
    stats.errors.push(`${testCase.name}: ${errorMsg}`);
    log('red', `❌ 请求失败: ${errorMsg} (${duration}ms)`);
    
    if (error.response?.data) {
      console.log('   错误详情:', JSON.stringify(error.response.data, null, 4));
    }
    
    return false;
  }
}

// 生成测试报告
function generateReport() {
  log('blue', '\n📊 测试报告');
  log('blue', '='.repeat(60));
  
  console.log(`\n📈 统计信息:`);
  console.log(`   总测试数: ${stats.total}`);
  console.log(`   通过: ${stats.passed} (${stats.total > 0 ? ((stats.passed / stats.total) * 100).toFixed(1) : 0}%)`);
  console.log(`   失败: ${stats.failed} (${stats.total > 0 ? ((stats.failed / stats.total) * 100).toFixed(1) : 0}%)`);
  
  if (stats.errors.length > 0) {
    log('red', '\n❌ 失败详情:');
    stats.errors.forEach(error => {
      console.log(`   • ${error}`);
    });
  }
  
  if (stats.passed === stats.total && stats.total > 0) {
    log('green', '\n🎉 所有测试都通过了！API接口工作正常。');
  } else if (stats.failed > 0) {
    log('yellow', '\n⚠️ 有测试失败，请检查后端接口实现。');
  }
  
  console.log(`\n⏰ 测试完成时间: ${new Date().toLocaleString()}`);
}

// 主测试函数
async function runTests() {
  log('magenta', '🚀 CreateTokenForm API 接口测试');
  log('magenta', '='.repeat(60));
  console.log(`🔗 API地址: ${API_BASE_URL}`);
  console.log(`⏰ 开始时间: ${new Date().toLocaleString()}\n`);
  
  // 健康检查
  const isHealthy = await healthCheck();
  if (!isHealthy) {
    log('red', '\n❌ 后端服务不可用，无法执行测试');
    process.exit(1);
  }
  
  // 测试辅助接口
  await testPrettyAddressEstimate();
  
  // 执行正常测试用例
  log('blue', '\n📝 执行正常功能测试...');
  for (const testCase of testCases) {
    await runTestCase(testCase);
    // 避免请求过快
    await new Promise(resolve => setTimeout(resolve, 1500));
  }
  
  // 执行错误测试用例
  log('blue', '\n🚨 执行错误处理测试...');
  for (const testCase of errorTestCases) {
    await runTestCase(testCase);
    await new Promise(resolve => setTimeout(resolve, 1000));
  }
  
  // 生成报告
  generateReport();
  
  // 设置退出码
  if (stats.failed > 0) {
    process.exit(1);
  } else {
    process.exit(0);
  }
}

// 错误处理
process.on('unhandledRejection', (reason) => {
  log('red', `未处理的Promise拒绝: ${reason}`);
  process.exit(1);
});

process.on('uncaughtException', (error) => {
  log('red', `未捕获的异常: ${error.message}`);
  process.exit(1);
});

// 运行测试
if (require.main === module) {
  runTests().catch(error => {
    log('red', `测试执行失败: ${error.message}`);
    process.exit(1);
  });
}

module.exports = { runTests };
